Hellforge General Crackme III
by LazaRuS


Tutorial de Lucifer48 [Immortal Descendants]
(13 ao√t 1999)



Le crackme est programmΘ en C++ builder, en gros τa ressemble α du delphi (je me demande lequel des deux est le pire ?). Le code est assez polluΘ, mais l'algorithme est ultra simple. Un bpx hmemcpy nous permet d'entrer dans le code:
XXXX:004028ED  CALL 004273E4		;rΘsultat: eax=longueur du nom (on sort d'ici)
XXXX:004028F2  LEA  EAX,[EBP-01DC]
XXXX:004028F8  CALL 0044DE94
XXXX:004028FD  INC  EAX			;longueur du nom +1
XXXX:004028FE  CMP  EDI,EAX		;edi est l'indice de boucle
XXXX:00402900  LEA  EAX,[EBP-01DC]
XXXX:00402906  SETL DL
XXXX:00402909  AND  EDX,01
XXXX:0040290C  PUSH EDX			;EDX=0 ou EDX=1
...
XXXX:0040291A  POP  ECX
XXXX:0040291B  TEST ECX,ECX		;si ECX=0, c'est la fin de la boucle
XXXX:0040291D  JNZ  0040285D		;retour dΘbut de la boucle
On voit qu'on attΘrit dans une boucle. Mais que fait cette (Θnorme) boucle ? En fait c'est trΦs simple, elle additionne seulement chaque valeur ascii des caractΦres du nom:
XXXX:004028A6  MOV  EDX,[EBP-0234]	;indice de boucle
XXXX:004028AC  ADD  EDX,[EBP-01E0]	;ajoute l'adresse du nom
XXXX:00402AB2  DEC  EDX
XXXX:00402AB3  MOVSX ECX,BYTE PTR [EDX]	;lit l'un des caractΦres du nom
XXXX:00402AB6  ADD  [EBP-0230],ECX	;grosse addition
Exemple: Pour mon nom (Lucifer48), j'obtient:
4C + 75 + 63 + 69 + 66 + 65 + 72 + 34 + 38 = 336h
Juste aprΦs la boucle:
XXXX:00402923  IMUL EAX,[EBP-0230],000A2D77
XXXX:0040292D  MOV  [EBP-230],EAX	;sauvegarde pour la comparaison finale
On continue:
XXXX:004029A5  CMP  EDI,EAX		;taille des deux serials
XXXX:004029A7  LEA  EAX,[EBP-01E8]	; edi: taille du premier serial
XXXX:004029AD  SETZ DL			; eax: taille du second serial
XXXX:004029B0  AND  EDX,01
XXXX:004029B3  PUSH EDX
...
XXXX:004029D4  POP  ECX
XXXX:004029D5  TEST CL,CL
XXXX:004029D7  JZ   00402B9C		;jump = les deux serials n'ont pas la mΩme taille
Donc pour pouvoir continuer, il faut que les deux serials soient de mΩme longueur. On arrive maintenant α la boucle des serials; lα encore, elle est Θnorme, mais en fait ce qu'elle fait est trΦs simple:
XXXX:00402A41  MOV  EDX,[EBP-023C]	;indice de boucle (k)
XXXX:00402A47  XOR  EAX,EAX
XXXX:00402A49  ADD  EDX,[EBP-01F0]	;adresse du premier serial
XXXX:00402A4F  DEC  EDX
XXXX:00402A50  MOV  CL,[EDX]		;lit le k-iΦme caractΦre du serial1
...
XXXX:00402A9A  MOV  EDX,[EBP-0240]	;indice de boucle (k)
XXXX:00402AA0  POP  EAX			;AL= k-iΦme caractΦre du serial1
XXXX:00402AA1  ADD  EDX,[EBP-01F4]	;adresse du second serial
XXXX:00402AA7  MOV  ECX,0000000A
XXXX:00402AAC  DEC  EDX
XXXX:00402AAD  XOR  AL,[EDX]		;xor avec le k-iΦme caractΦre du serial2
XXXX:00402AAF  MOVSX EAX,AL
XXXX:00402AB2  CDQ
XXXX:00402AB3  IDIV ECX
XXXX:00402AB5  MOVSX EDX,DL		;instruction inutile ici
...
XXXX:00402B93  POP  ECX			;ecx=0 ou ecx=1
XXXX:00402B94  TEST ECX,ECX
XXXX:00402B96  JNZ  004029F2		;si ecx=1 alors la boucle n'est pas finie
Ansi chaque reste de la division euclidienne va Ωtre gardΘ et mis bout α bout (via une procΘdure similaire α wfprintf). On arrive maintenant α la comparaison finale:
XXXX:00402BBF  LEA  EDX,[EBP-0200]	;d *edx: rΘsultat du nom (ce qu'il faut trouver)
XXXX:00402BC5  LEA  EAX,[EBP-10]	;d *eax: code issu des modulos (serial)
XXXX:00402BC8  CALL 0044DE7C		;comparaison
XXXX:00402BCD  PUSH EAX
...
XXXX:00402BE1  POP  ECX
XXXX:00402BE2  TEST CL,CL
XXXX:00402BE4  JZ   00402C14		;jmp = mauvais serials
Voilα la registration la plus facile (pour moi):
Name/ Lucifer48
Serial/ 548273178
Serial/ 000000000

ou

Serial/ 548273179
Serial/ 000000001

...

Serial/ <=1;>:8>1
Serial/ 999999999

Prendre des chiffres est la faτon la plus simple, car on ne se soucit pas de la division euclidienne. Une derniΦre...

Name/ Lucifer48
Serial/ Lucifer48
Serial/ 15E516530

C'est fini !

Greetings: All ID members (Volatility, Torn@do, ...), Eternal Bliss, ACiD BuRN, Duelist, LaZaRuS, people on #cracking4newbies, french crackers, and other crackme makers.



(c) Lucifer48. All rights reversed